package ce.com.cenewbluesdk.queue;



import ce.com.cenewbluesdk.CEBC;
import ce.com.cenewbluesdk.entity.CEDevData;
import ce.com.cenewbluesdk.entity.QueueSendData;
import ce.com.cenewbluesdk.uitl.ByteUtil;
import ce.com.cenewbluesdk.uitl.CRC16;
import ce.com.cenewbluesdk.uitl.Lg;

/**
 * Created by Administrator on 2016/11/17 0017.
 */
public class CEProtocolB extends CEProtocolBase {

    /**
     * 头包的有效字节数
     */
    private static final int headpageL=10;

    private int devType;
    private CEDevData currDevData;

    public CEProtocolB(int devType) {
        this.devType = devType;
    }

    @Override
    public QueueSendData getSendData(CEDevData devData) {
        byte[] bytes = new byte[20];

        if (devData.getCmd() == CEBC.CMD_APP_ACK_TYPE) {
            // 一个要回Ack的数据包
            bytes[0] = 0;
            bytes[1] = (byte) devType;
            bytes[2] = (byte) 0;
            bytes[3] = (byte) devData.getN();
            bytes[4] = CEBC.K2.CMD_TYPE_ACK;
            bytes[5] = (byte) devData.getDataType();


            bytes[8] = (byte) (1 & 0xff);
            bytes[9] = (byte) (1 >> 8);
            if (devData.getDataCrc16() == devData.figureCrc16()) {
                bytes[headpageL] = CEBC.K2.CMD.ACK_TYPE_SUCCESS;
            } else {
                bytes[headpageL] = CEBC.K2.CMD.ACK_TYPE_CRC16_WRONG;
            }

            int tCrcSum = CRC16.crc16(new byte[]{bytes[headpageL]});

            System.arraycopy(ByteUtil.int2bytes2(tCrcSum), 0, bytes,6 , 2);
        } else if (devData.getCurrentIndex() == 0) {
            // TODO: 2016/11/17 0017  发送第一个包;
            bytes[0] = 0;
            bytes[1] = (byte) devType;

            int dataL = 0;
            if (devData.getData() != null)
                dataL = devData.getData().length;

            int totalPage = getPageNumber(dataL);
            devData.setTotalIndex(totalPage);
            bytes[2] = (byte) totalPage;
            bytes[3] = (byte) devData.getN();
            bytes[4] = (byte) devData.getCmd();
            bytes[5] = (byte) devData.getDataType();

            int tCrcSum = devData.figureCrc16();
            Lg.e("liu  tCrcSum="+tCrcSum);

            System.arraycopy(ByteUtil.int2bytes2(tCrcSum), 0, bytes,6 , 2);
            System.arraycopy(ByteUtil.int2bytes2(dataL), 0, bytes,8 , 2);

            if (dataL > 0 && dataL <= headpageL) {
                System.arraycopy(devData.getData(), 0, bytes, headpageL, dataL);
            } else if (dataL > headpageL) {
                System.arraycopy(devData.getData(), 0, bytes, headpageL, 20-headpageL);
            }
        } else {
            bytes[0] = (byte) devData.getCurrentIndex();
//            if (devData.getCurrentIndex() >= devData.getTotalIndex()) {
//                return null;
//            }
            int currDataIndex = headpageL + (devData.getCurrentIndex() - 1) * 19;
            if (devData.getData().length >= currDataIndex + 19) {
                System.arraycopy(devData.getData(), currDataIndex, bytes, 1, 19);
            } else {
                int sendDataL = devData.getData().length - currDataIndex;
                System.arraycopy(
                        devData.getData(), currDataIndex, bytes, 1, sendDataL);
            }

        }
        QueueSendData queueSendData = new QueueSendData();
        queueSendData.setSendData(bytes);
        return queueSendData;
    }

    @Override
    public CEDevData Analysis(byte[] bytes) {
        if (bytes[0] == 0) {
            // TODO: 2016/11/17 0017  头包。
            if (bytes[4] == CEBC.K2.CMD_TYPE_ACK) {  //  设备侧回的Ack
                CEDevData data = new CEDevData();
                data.setCmd(CEBC.AckApp.CMD_ACK);
                data.setDataType(bytes[5]);
                data.setN(bytes[3]&0xff);
                data.setData(convertACK(bytes[headpageL]));
                return data;
            } else {
                currDevData = new CEDevData();
                currDevData.setCurrentIndex(0);
                currDevData.setTotalIndex(bytes[2]);
                currDevData.setCmd(bytes[4]);
                currDevData.setDataType(bytes[5]);
                currDevData.setN(bytes[3]&0xff);
                currDevData.setDataCrc16(ByteUtil.byte2ToInt(new byte[]{bytes[6], bytes[7]}));
                currDevData.setData(new byte[ByteUtil.byte2ToInt(new byte[]{bytes[8], bytes[9]})]);
                byte[] datab = currDevData.getData();
                if (currDevData.getTotalIndex() == 0) {//表示只有一20字节
                    if (datab.length <= headpageL) {
                        System.arraycopy(bytes, headpageL, datab, 0, datab.length);
                        currDevData.setCmd(CEBC.CMD_APP_ACK_TYPE);
                        return currDevData;
                    } else {
                        Lg.e("设备侧给的数据异常  1  :" + CEBC.byte2hex(bytes));
                    }
                } else {
                    if (datab.length > headpageL) {
                        System.arraycopy(bytes, headpageL, datab, 0, 20-headpageL);
                    } else {
                        Lg.e("设备侧给的数据异常  2  :" + CEBC.byte2hex(bytes));
                    }
                }
            }
        } else {
            if (currDevData == null) {
                Lg.e("设备侧给的数据异常  3  没有收到头包 :" + CEBC.byte2hex(bytes));
                return null;
            } else {
                if (currDevData.getCurrentIndex() + 1 != bytes[0]) {
                    Lg.e("设备侧给的数据异常  4  收到了跳变的字节数组 curr=" +
                            currDevData.getCurrentIndex() + "设备侧给的：" + bytes[0]);
                } else {
                    currDevData.setCurrentIndex(bytes[0]);
                    byte[] datab = currDevData.getData();

                    int currDataByteIndex = headpageL + (currDevData.getCurrentIndex() - 1) * 19;
                    if (datab.length >= currDataByteIndex + 19) {
                        System.arraycopy(bytes, 1, datab, currDataByteIndex, 19);
                    } else {
                        System.arraycopy(bytes, 1, datab, currDataByteIndex, datab.length - currDataByteIndex);
                    }
                    if (currDevData.getCurrentIndex() >= currDevData.getTotalIndex()) {
                        currDevData.setCmd(CEBC.CMD_APP_ACK_TYPE);
                        return currDevData;
                    }
                }
            }
        }
        return null;
    }

    @Override
    public void removeMapData(Integer dateTypeKey) {

    }

    @Override
    public byte[] convertACK(byte ack) {
        byte appAck = CEBC.AckApp.ACK_TYPE_NULL;
        switch (ack) {
            case 1:
                appAck = CEBC.AckApp.ACK_TYPE_SUCCESS;
                break;
            case 2:
                appAck = CEBC.AckApp.ACK_TYPE_WRONG;
                break;
            case 3:
                appAck = CEBC.AckApp.ACK_TYPE_CRC16_WRONG;
                break;
            case 4:
                appAck = CEBC.AckApp.ACK_TYPE_OVER;
                break;
        }
        return new byte[]{appAck};
    }


    private int getPageNumber(int bytesL) {
        if (bytesL <= headpageL) {
            return 0;
        }
        int n = (bytesL - headpageL) / 19;
        if ((bytesL - headpageL) % 19 > 0) {
            n++;
        }
        if (n > 255) {
            n = 255;
        }
        return n;
    }
}
